package com.lanyan.common.utils.wx;

import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.google.gson.Gson;
import com.lanyan.common.core.redis.RedisCache;
import com.lanyan.common.exception.ServiceException;
import com.lanyan.common.utils.http.HttpUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import java.io.*;
import java.net.ConnectException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.*;

@Component
public class WxAppletUserInfo {

    @Autowired
    private RedisCache redisCache;

    public static JSONObject getSessionKeyOropenid(String code, String appId, String secret){
        //微信端登录code值

        Map<String,String> requestUrlParam = new HashMap<String,String>();
        requestUrlParam.put("appid", appId);	//开发者设置中的appId
        requestUrlParam.put("secret", secret);	//开发者设置中的appSecret
        requestUrlParam.put("js_code", code);	//小程序调用wx.login返回的code
        requestUrlParam.put("connect_redirect", "1");
        requestUrlParam.put("grant_type", "authorization_code");	//默认参数
        //发送post请求读取调用微信 https://api.weixin.qq.com/sns/oauth2/access_token 接口获取openid用户唯一标识
        JSONObject jsonObject = JSON.parseObject(sendPost(WxParameter.OPENID_URL, requestUrlParam));

        return jsonObject;
    }


    //微信敏感词审核
    public JSONObject checkwords(String content,String appId,String secret){
        String accessToken = WxAppletUserInfo.getMPToken(appId, secret);  //获取token
        String url="https://api.weixin.qq.com/wxa/msg_sec_check?access_token="+ accessToken;
        Map<String, Object> map = new HashMap<String, Object>();
        //map.put("access_token",accessToken);
        map.put("content", content);

        JSONObject result = JSON.parseObject(sendJsonPost(url, JSON.toJSONString(map)));
        return result;
    }


//    //敏感词审核
//    public static  Boolean checkContent(String content,String appId,String secret) {
//        try {
//            JSONObject jsonObject = WxAppletUserInfo.getMPToken(appId, secret);
//            System.out.println("content:"+content);
//            String accessToken = jsonObject.getString("access_token");
//            CloseableHttpClient httpclient = HttpClients.createDefault();
//            CloseableHttpResponse response = null;
//            HttpPost request = new HttpPost("https://api.weixin.qq.com/wxa/msg_sec_check?access_token=" + accessToken);
//            request.addHeader("Content-Type", "application/json");
//            Map<String, String> map = new HashMap<>();
//            map.put("content",content);
//            String body = JSONObject.toJSONString(map);
//            request.setEntity(new StringEntity(body, ContentType.create("text/json", "UTF-8")));
//            response = httpclient.execute(request);
//            HttpEntity httpEntity = response.getEntity();
//            String result = EntityUtils.toString(httpEntity, "UTF-8");// 转成string
//            JSONObject jso = JSONObject.parseObject(result);
//            return getResult(jso);
//        } catch (Exception e) {
//            e.printStackTrace();
//            System.out.println("----------------调用腾讯内容过滤系统出错------------------");
//            return true;
//        }
//    }

    //敏感词审核
    private static Boolean  getResult(JSONObject jso){
        Object errcode = jso.get("errcode");
        int errCode = (int) errcode;
        if (errCode == 0) {
            System.out.println("文字内容正常-------");
            return true;
        } else if (errCode == 87014) {
            System.out.println("文字内容违规-------");
            return false;
        }
        return true;
    }



//    public synchronized  String getToken(){
//        Token token = tokenMapper.getToken().get(0);
//        Long now = new Date().getTime()/1000;
//        System.out.println(now - token.getCreateTime());
//        String tk;
//        if( now - token.getCreateTime() > 7200){
//            Map<String,String> requestUrlParam = new HashMap<String,String>();
//            requestUrlParam.put("appid", WxParameter.APP_ID);	//开发者设置中的appId
//            requestUrlParam.put("secret", WxParameter.APP_SECRET);	//开发者设置中的appSecret
//            requestUrlParam.put("grant_type", "client_credential");	//默认参数
//            JSONObject jsonObject = JSON.parseObject(sendPost(WxParameter.TOKEN_URL, requestUrlParam));
//            System.out.println(new Date()+ ",2.获取到了Token"+jsonObject.get("access_token"));
//            Token t = new Token();
//            t.setId(1);
//            t.setAccessToken(jsonObject.get("access_token").toString());
//            t.setCreateTime(now);
//           tokenMapper.updateById(t);
//            tk = jsonObject.get("access_token").toString();
//        }else{
//            tk = token.getAccessToken();
//            System.out.println(new Date()+ ",获取到了2"+token);
//        }
//       return tk;
//   }

    //获取access token
    public static String getMPToken(String appId,String secret){
        Map<String,String> requestUrlParam = new HashMap<String,String>();
        requestUrlParam.put("appid", appId);	//开发者设置中的appId
        requestUrlParam.put("secret", secret);	//开发者设置中的appSecret
        requestUrlParam.put("grant_type", "client_credential");	//默认参数
        JSONObject jsonObject = JSON.parseObject(sendPost(WxParameter.TOKEN_URL, requestUrlParam));
        String sessionkey = jsonObject.getString("access_token");
        return sessionkey;
    }




    public static JSONObject getSubscribe(String openId,String token){
        Map<String,String> requestUrlParam = new HashMap<String,String>();
        requestUrlParam.put("openid", openId);	//开发者设置中的appId
        requestUrlParam.put("access_token", token);	//开发者设置中的appSecret
        requestUrlParam.put("lang", "zh_CN");	//默认参数
        JSONObject jsonObject = JSON.parseObject(sendPost(WxParameter.INFO_URL, requestUrlParam));
        return jsonObject;
    }

//    public Map getUnionId(String openId) {
//        String access_token = wxAppletUserInfo.getToken();
//        Map<String,String> requestUrlParam = new HashMap<String,String>();
//        requestUrlParam.put("openid", openId);	//开发者设置中的appId
//        requestUrlParam.put("access_token", access_token);	//开发者设置中的appSecret
//        requestUrlParam.put("lang", "zh_CN");	//默认参数
//        JSONObject jsonObject = JSON.parseObject(sendPost(WxParameter.INFO_URL, requestUrlParam));
//        System.out.println("3.获取到了UnionId"+jsonObject);
//        return jsonObject;
//    }

    //逆地址解析
    public static Map<String, Object> getLocation(String lat, String lng) {

        Map<String, Object> resultMap = new HashMap<String, Object>();

        // 参数解释：lng：经度，lat：维度。KEY：腾讯地图key，get_poi：返回状态。1返回，0不返回
        String urlString = "http://apis.map.qq.com/ws/geocoder/v1/?location=" + lat + "," + lng + "&key=" + "TGGBZ-LQQKW-JRXR6-OQ4QJ-PPENH-RUFL6";
        String result = "";
        try {
            URL url = new URL(urlString);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setDoOutput(true);
            // 腾讯地图使用GET
            conn.setRequestMethod("GET");
            BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8));
            String line;
            // 获取地址解析结果
            while ((line = in.readLine()) != null) {
                result += line + "\n";
            }
            in.close();
        } catch (Exception e) {
            e.getMessage();
        }

        // 转JSON格式
        JSONObject jsonObject = JSON.parseObject(result);
        // 获取地址（行政区划信息） 包含有国籍，省份，城市

        JSONObject result1 = jsonObject.getJSONObject("result");

        JSONObject adInfo = result1.getJSONObject("ad_info");


        resultMap.put("province", adInfo.get("province"));
        resultMap.put("city", adInfo.get("city"));
        resultMap.put("district", adInfo.get("district"));
        return resultMap;
    }



//    public JSONObject getUserInfo(String encryptedData,String sessionKey,String iv){
//        // 被加密的数据
//        byte[] dataByte = Base64.encodeBase64(encryptedData.getBytes());
//        // 加密秘钥
//        byte[] keyByte = Base64.encodeBase64(sessionKey.getBytes());
//        // 偏移量
//        byte[] ivByte = Base64.encodeBase64(iv.getBytes());
//        try {
//            // 如果密钥不足16位，那么就补足.  这个if 中的内容很重要
//            int base = 16;
//            if (keyByte.length % base != 0) {
//                int groups = keyByte.length / base + (keyByte.length % base != 0 ? 1 : 0);
//                byte[] temp = new byte[groups * base];
//                Arrays.fill(temp, (byte) 0);
//                System.arraycopy(keyByte, 0, temp, 0, keyByte.length);
//                keyByte = temp;
//            }
//            // 初始化
//            Security.addProvider(new BouncyCastleProvider());
//            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding","BC");
//            SecretKeySpec spec = new SecretKeySpec(keyByte, "AES");
//            AlgorithmParameters parameters = AlgorithmParameters.getInstance("AES");
//            parameters.init(new IvParameterSpec(ivByte));
//            cipher.init(Cipher.DECRYPT_MODE, spec, parameters);// 初始化
//            byte[] resultByte = cipher.doFinal(dataByte);
//            if (null != resultByte && resultByte.length > 0) {
//                String result = new String(resultByte, StandardCharsets.UTF_8);
//                return JSON.parseObject(result);
//            }
//        } catch (Exception e) {
//
//        }
//        return null;
//    }

    public static String sendPost(String url, Map<String, ?> paramMap) {
        PrintWriter out = null;
        BufferedReader in = null;
        String result = "";
        String param = "";
        Iterator<String> it = paramMap.keySet().iterator();

        while(it.hasNext()) {
            String key = it.next();
            param += key + "=" + paramMap.get(key) + "&";
        }
        try {
            URL realUrl = new URL(url);
            // 打开和URL之间的连接
            URLConnection conn = realUrl.openConnection();
            // 设置通用的请求属性
            conn.setRequestProperty("accept", "*/*");
            conn.setRequestProperty("connection", "Keep-Alive");
            conn.setRequestProperty("Accept-Charset", "utf-8");
            conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            // 发送POST请求必须设置如下两行
            conn.setDoOutput(true);
            conn.setDoInput(true);
            // 获取URLConnection对象对应的输出流
            out = new PrintWriter(conn.getOutputStream());
            // 发送请求参数
            out.print(param);
            // flush输出流的缓冲
            out.flush();
            // 定义BufferedReader输入流来读取URL的响应
            in = new BufferedReader(new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8));
            String line;
            while ((line = in.readLine()) != null) {
                result += line;
            }
        } catch (Exception e) {

        }
        //使用finally块来关闭输出流、输入流
        finally{
            try{
                if(out!=null){
                    out.close();
                }
                if(in!=null){
                    in.close();
                }
            }
            catch(Exception ex){
                ex.printStackTrace();
            }
        }
        return result;
    }

    public static String sendJsonPost(String url, String paramMap ) {
        PrintWriter out = null;
        BufferedReader in = null;
        String result ="";
        String params = "";
        params = new Gson().toJson(paramMap);
        System.out.println("json字符串" + params);

        try {
            URL realUrl = new URL(url);
            // 打开和URL之间的连接
            URLConnection conn = realUrl.openConnection();
            // 设置通用的请求属性
            conn.setRequestProperty("accept", "*/*");
            conn.setRequestProperty("connection", "Keep-Alive");
            conn.setRequestProperty("Accept-Charset", "utf-8");
            conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            // 发送POST请求必须设置如下两行
            conn.setDoOutput(true);
            conn.setDoInput(true);
            // 获取URLConnection对象对应的输出流
            out = new PrintWriter(conn.getOutputStream());
            // 发送请求参数
            out.print(params);
            // flush输出流的缓冲
            out.flush();
            // 定义BufferedReader输入流来读取URL的响应
            in = new BufferedReader(new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8));
            String line;
            while ((line = in.readLine()) != null) {
                result += line;
            }
        } catch (Exception e) {

        }
        //使用finally块来关闭输出流、输入流
        finally{
            try{
                if(out!=null){
                    out.close();
                }
                if(in!=null){
                    in.close();
                }
            }
            catch(Exception ex){
                ex.printStackTrace();
            }
        }
        return result;
    }
    public static JSONObject httpsRequest(String requestUrl, String requestMethod, String outputStr) {
        JSONObject jsonObject = null;
        try {
            // 创建SSLContext对象，并使用我们指定的信任管理器初始化
            TrustManager[] tm = { new MyTrustManager() };
            SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
            sslContext.init(null, tm, new java.security.SecureRandom());
            // 从上述SSLContext对象中得到SSLSocketFactory对象
            SSLSocketFactory ssf = sslContext.getSocketFactory();

            URL url = new URL(requestUrl);
            HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
            conn.setSSLSocketFactory(ssf);

            conn.setDoOutput(true);
            conn.setDoInput(true);
            conn.setUseCaches(false);
            // 设置请求方式（GET/POST）
            conn.setRequestMethod(requestMethod);

            // 当outputStr不为null时向输出流写数据
            if (null != outputStr) {
                OutputStream outputStream = conn.getOutputStream();
                // 注意编码格式
                outputStream.write(outputStr.getBytes(StandardCharsets.UTF_8));
                outputStream.close();
            }

            // 从输入流读取返回内容
            InputStream inputStream = conn.getInputStream();
            InputStreamReader inputStreamReader = new InputStreamReader(inputStream, StandardCharsets.UTF_8);
            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
            String str = null;
            StringBuffer buffer = new StringBuffer();
            while ((str = bufferedReader.readLine()) != null) {
                buffer.append(str);
            }

            // 释放资源
            bufferedReader.close();
            inputStreamReader.close();
            inputStream.close();
            inputStream = null;
            conn.disconnect();
            jsonObject = JSONObject.parseObject(buffer.toString());
        } catch (ConnectException ce) {
        } catch (Exception e) {
        }
        return jsonObject;
    }

    public static Object sendGet(String url, String param) {
        String result = "";
        BufferedReader in = null;
        try {
            String urlNameString = url + "/" + param;
            URL realUrl = new URL(urlNameString);
            // 打开和URL之间的连接
            URLConnection connection = realUrl.openConnection();
            // 设置通用的请求属性
            connection.setRequestProperty("accept", "*/*");
            connection.setRequestProperty("connection", "Keep-Alive");
            connection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            // 建立实际的连接
            connection.connect();
            // 获取所有响应头字段
            Map<String, List<String>> map = connection.getHeaderFields();
            // 遍历所有的响应头字段
            for (String key : map.keySet()) {
                System.out.println(key + "--->" + map.get(key));
            }
            // 定义 BufferedReader输入流来读取URL的响应
            in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
            String line;
            while ((line = in.readLine()) != null) {
                result += line;
            }
        } catch (Exception e) {
            System.out.println("发送GET请求出现异常！" + e);
            e.printStackTrace();
        }
        // 使用finally块来关闭输入流
        finally {
            try {
                if (in != null) {
                    in.close();
                }
            } catch (Exception e2) {
                e2.printStackTrace();
            }
        }
        return result;
    }


    private static class MyTrustManager implements TrustManager {
    }

    private class GetWebAccessToken {
    }


    @GetMapping("/sendWx")
    public static void sendWx(String payNo,String openId,String appId,String secret,String machId){
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
        String mpToken = WxAppletUserInfo.getMPToken(appId, secret);
        JSONObject params = new JSONObject();
//        params.put("access_token",mpToken);//接口调用凭证，该参数为 URL 参数，非 Body 参数。使用getAccessToken或者authorizer_access_token
        JSONObject orderKey = new JSONObject();
        orderKey.put("order_number_type",2);//订单单号类型，用于确认需要上传详情的订单。枚举值1，使用下单商户号和商户侧单号；枚举值2，使用微信支付单号。
        orderKey.put("transaction_id ",payNo);
        orderKey.put("mchid",machId);
        params.put("order_key",orderKey);
        params.put("logistics_type",4);//物流模式，发货方式枚举值：1、实体物流配送采用快递公司进行实体物流配送形式 2、同城配送 3、虚拟商品，虚拟商品，例如话费充值，点卡等，无实体配送形式 4、用户自提
        params.put("delivery_mode",1);//发货模式，发货模式枚举值：1、UNIFIED_DELIVERY（统一发货）2、SPLIT_DELIVERY（分拆发货） 示例值: UNIFIED_DELIVERY
        JSONArray shippingList = new JSONArray();
        JSONObject shippingListItem = new JSONObject();
        shippingListItem.put("item_desc","订单商品");//商品信息，例如：微信红包抱枕*1个，限120个字以内
        shippingList.add(shippingListItem);
        params.put("shipping_list",shippingList);
        params.put("upload_time",sdf.format(new Date()));//上传时间，用于标识请求的先后顺序 示例值: `2022-12-15T13:29:35.120+08:00`
        JSONObject payer = new JSONObject();
        payer.put("openid",openId);
        params.put("payer",payer);
        System.out.println(params.toString());
        HttpUtils.sendPost("https://api.weixin.qq.com/wxa/sec/order/upload_shipping_info?access_token="+mpToken,params.toJSONString());
    }


    /**
     * 发货信息录入接口-模拟入参
     */
    private static WxDeliverGoodsDTO getWxDeliverGoodsVo(String openId, String content, String orderNumber, String mchId, String tranId){
        WxDeliverGoodsDTO vo = new WxDeliverGoodsDTO();
        OrderKeyDTO order_key = new OrderKeyDTO();
        order_key.setMchid(mchId);
        order_key.setOrder_number_type(1);	// 必填
        order_key.setOut_trade_no(orderNumber);
        order_key.setTransaction_id(orderNumber);

        ArrayList<ShippingDTO> list = new ArrayList<>();
        ShippingDTO shipping = new ShippingDTO();
        shipping.setExpress_company("");
        shipping.setItem_desc(content);	// 必填
        shipping.setTracking_no("");
        ContactDTO contact = new ContactDTO();
//		contact.setConsignor_contact("+86-177****1234");
        contact.setConsignor_contact("");	// 手机号掩码处理
        contact.setReceiver_contact("");
        shipping.setContact(contact);
        list.add(shipping);

        PayerDTO payer = new PayerDTO();
        payer.setOpenid(openId);	// 必填

        vo.setOrder_key(order_key);	// 必填
        vo.setLogistics_type(3);	// 必填
        vo.setDelivery_mode(1);		// 必填
        vo.setIs_all_delivered(null);	// 分拆发货模式时必填
        vo.setShipping_list(list);	// 必填
//		vo.setUpload_time("2022-12-15T13:29:35.120+08:00");	// 必填
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
        vo.setUpload_time(sdf.format(new Date()));	// 必填
        vo.setPayer(payer);	// 必填

        return vo;
    }

    /**
     * 微信小程序-发货信息录入接口
     * */
    public static void test01(String openId,
                              String content,
                              String orderNumber,
                              String mchId,
                              String appId,
                              String secret,
                              String tranId){
        try {
            String accessToken = getMPToken(appId,secret);
            String url = "https://api.weixin.qq.com/wxa/sec/order/upload_shipping_info?access_token="+accessToken+"";
            /* 获取模拟入参 */
            WxDeliverGoodsDTO vo = getWxDeliverGoodsVo(openId, content, orderNumber,mchId, tranId);
            String param = JSONObject.toJSONString(vo);
            System.out.println("入参 = " + param);
            String result = HttpUtil.post(url, param);

            JSONObject jsonObject = JSON.parseObject(result);
            int errcode = jsonObject.getInteger("errcode");
            if (errcode != 0) {
                String errmsg = jsonObject.getString("errmsg");
                String err = String.format("微信小程序-发货信息录入接口异常，code码：%s, msg：%s", errcode, errmsg);
                throw new ServiceException( "微信小程序-发货信息录入接口异常：" + errmsg,errcode);
            }
        } catch (Exception e) {
            throw new ServiceException(e.getMessage());
        }
    }
}
